
import threading
from concurrent import futures
import time

class FooBar():
    def __init__(self, n):
        self.n = n
        self.event = threading.Event()
        self.event2 = threading.Event()

    def foo(self):
        for i in range(self.n):
            self.event2.wait()                 # 阻塞等待
            print('foo', end='')
            self.event.set()                   # 给bar传信息，可以执行
            self.event2.clear()                # 自动设置阻塞

    def bar(self):
        self.event2.set()                    # 给foo传信息可以执行
        for i in range(self.n):
            self.event.wait()                # 阻塞等待
            print('bar', end='')
            self.event2.set()                # 给foo传信息可以执行
            self.event.clear()               # 自动设置阻塞

def threadpool(funcs, n=2):
    lst = []
    executer = futures.ThreadPoolExecutor(max_workers=n)            # 开启一个线程池
    for i in funcs:
        lst.append(executer.submit(i))                              # 开启线程

    while True:                                                    # 线程执行结束，关闭线程池
        time.sleep(1)
        flag = True
        for j in lst:
            flag = flag and j.done()

        if flag:
            executer.shutdown()
            break

foobar = FooBar(3)
threadpool((foobar.foo, foobar.bar))


# 使用线程池的思路非常好，但是对于一些简单的问题，可能需要考虑一下线程池的初始化耗时问题。
# 根据具体的情况来进行取舍。